<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试ajax封装</title>
</head>

<body>
    <button id="btn">点击测试ajax请求</button>
    <script>
        /* 封装过程和基本测试过程必须要会写
        封装一个GET类型AJAX请求函数
        需要两个对象：  XHR + promise
        内部使用xhr发异步ajax请求, 返回一个promise对象
        */
        let btn = document.querySelector('#btn');
        function ajax(url) {
            return new Promise((resolve, reject) => {
                //1.创建xhr
                let xhr = new XMLHttpRequest();
                //2.初始化
                xhr.open('GET', url);
                //3.绑定事件
                xhr.onreadystatechange = () => {
                    console.log('onreadystatechange ()');
                    if (xhr.readyState !== 4) return  //这是处理请求没有返回的情况，直接return，不用作处理
                    //请求返回后修改promise的状态，如果成功了，将其状态更新为成功，并指定value
                    if (xhr.status >= 200 && xhr.status < 300) {
                        //成功的value指定为响应体中json数据对应的js对象/数组
                        resolve(JSON.parse(xhr.responseText)) //需要将数据转换成对象的原因是浏览器中可以看出response中是JSON格式
                    } else {//如果失败了，将promise更新为失败状态，并指定reason
                        reject(new Error(`请求失败 status=${xhr.status}`)) //Error是ES6中的内置构造函数
                    }
                }
                //4.发送请求
                xhr.send();
            })
        }
        //1，测试使用ajax发送请求的方式之一，绑定点击事件，用async和await方式
        btn.onclick = async () => {//把async关键字放在函数前面，会把函数的返回值变成promise的实例对象

            //没有用到await的情况，有成功或失败
            // const result=ajax('http://localhost:8080/movie');//如果是错误参数或路径，则弹出框信息为404
            // p.then(result => console.log('请求成功的数据',result),
            // error => alert(error.message))

            //用到await的情况 如果在await后面书写的是失败的promise实例对象，使用try catch处理
            // try{
            //     //成功
            //     const result =await ajax('http://localhost:8080/movie2') //路径中不存在目标值

            // }catch(e){//失败
            //     alert(error.message)
            // }
        }

        //2，测试使用ajax发送请求的方式之二，也是async和await方式
        // async function request(){
        //     const result=await ajax('http://localhost:3000/movie?id=3');//正确地址
        //     // const result=await ajax('http://localhost:3000/movie2?id=3');//错误地址

        //      return result;//返回的是我们定义好的json数据中的movie数组，如果不返回，就是undefined
        // }
        
         //2.1，测试ajax请求方式之await后面是一个非promise对象的返回值
        async function test() {
            // const result =await 2; //此时的await后面就不是promise对象
            const result = await { age: 18 }; //此时的await后面就不是promise对象
            const promise = request();
            console.log(promise);//Promise 2  Promsie {age:18}
        }
        test();
        
        //2.2 async函数返回的promise由什么决定？函数执行的结果决定(与then的特点一致)
        // function test(){
        //     //调用async修饰的函数返回的结果是一个新的promise对象
        //   const promise = request();

        //   /*此时如果请求地址和参数都是正确的，则打印结果的状态是成功的，value是undefined或
        //   者request函数的return值result;反之，地址错误，则是rejected失败状态，提示status=404*/
        //   console.log(promise);
        // }
        // test();
        /*总结:async函数返回的promise由什么决定？函数执行的结果决定(与then的特点一致)*/
    </script>
</body>

</html>